
AC_PREREQ([2.67])
AC_INIT([xpkit],[0.1.21],[Chung, Hyung-Hwan (hyunghwan.chung@abiyo.net)])
AC_CONFIG_HEADER([include/xp/config.h])
AC_CONFIG_AUX_DIR(ac)
AC_CONFIG_MACRO_DIR(m4)

dnl use CC and CPP for compilation tests with .c test programs.
AC_LANG(C)

dnl initialize automake
AM_INIT_AUTOMAKE([-Wall -Werror foreign])

dnl determine a C compiler to use
AC_PROG_CC

dnl determine a C++ compiler to use
AC_PROG_CXX

dnl check if the C++ compiler exists in PATH
AC_CHECK_PROG(HAVE_CXX, $CXX, yes, no)

dnl determine some key programs
AC_PROG_INSTALL
AC_PROG_EGREP
AC_PROG_LN_S

dnl check other tools
AC_CHECK_TOOL(RM, rm)
AC_CHECK_TOOL(RMDIR, rmdir)
AC_CHECK_TOOL(TRUE, true)
AC_CHECK_TOOL(ECHO, echo)

dnl avoid "'/bin/rm: cannot remove `libtoolT': No such file or directory"
RM="$RM -f"

dnl initialize libtool
LT_INIT([])
AC_SUBST(LIBTOOL_DEPS)

dnl make visible the 64-bit interface to the file system
CFLAGS="$CFLAGS -D_LARGEFILE64_SOURCE -DXPKIT_HAVE_CONFIG_H"
CXXFLAGS="$CXXFLAGS -D_LARGEFILE64_SOURCE -DXPKIT_HAVE_CONFIG_H"

dnl define the WIN32 conditional if necessary
case "$host" in
*-*-mingw*|*-*-cygwin*)
	platform_win32=yes
	CFLAGS="$CFLAGS -D_WIN32_WINNT=0x0501"
	CXXFLAGS="$CXXFLAGS -D_WIN32_WINNT=0x0501"
esac
AM_CONDITIONAL(WIN32, test "${platform_win32}" = "yes" )

dnl check the math library (check if -lm is needed)
LT_LIB_M([])
AC_SUBST(LIBM, $LIBM)

dnl check other libraries
AC_CHECK_LIB(pthread, pthread_create)
AC_CHECK_LIB(nsl, gethostbyname)
AC_CHECK_LIB(socket, connect)
AC_CHECK_LIB(rt, nanosleep)
AC_CHECK_LIB(dl, dlopen, [ 
	LIBDL=-ldl
	AC_SUBST(LIBDL, $LIBDL) 
], [])

dnl checks header files.
AC_HEADER_STDC
AC_CHECK_HEADER([sys/syscall.h], [AC_DEFINE([XP_HAVE_SYS_SYSCALL_H],[],[sys/syscall.h])])
AC_CHECK_HEADER([wchar.h], [AC_DEFINE([XP_HAVE_WCHAR_H],[],[wchar.h])])
AC_CHECK_HEADER([pthread.h], [AC_DEFINE([XP_HAVE_PTHREAD_H],[],[pthread.h])])
AC_CHECK_HEADER([poll.h], [AC_DEFINE([XP_HAVE_POLL_H],[],[poll.h])])
AC_CHECK_HEADER([sys/epoll.h], [AC_DEFINE([XP_HAVE_SYS_EPOLL_H],[],[sys/epoll.h])])

AC_CHECK_HEADER([security/pam_appl.h], [
	LIBS="$LIBS -lpam"
	AC_DEFINE([XP_HAVE_PAM],[],[PAM Authentication])])

AC_CHECK_HEADERS([fcntl.h kvm.h sys/sysinfo.h sys/sysctl.h ifaddrs.h])
AC_CHECK_HEADERS([linux/netfilter_ipv4/ipt_mark.h])
AC_CHECK_HEADERS([linux/netfilter_ipv4/ipt_connlimit.h])
AC_CHECK_HEADERS([linux/netfilter/xt_connlimit.h])
AC_CHECK_HEADERS([net/ip_vs.h])
AC_CHECK_HEADERS([linux/ip_vs.h])

dnl checks for win32 pdh.h
AC_CHECK_HEADER([pdh.h])

AC_CHECK_HEADER([sys/sysinfo.h], [
	AC_CHECK_MEMBER(struct sysinfo.mem_unit,
		[AC_DEFINE([XP_HAVE_SYS_SYSINFO_MEM_UNIT],[],[sys/sysinfo.mem_unit])],
		[],
		[#include <sys/sysinfo.h>])]
)

AC_CHECK_MEMBER(struct sockaddr_in6.sin6_scope_id,
	[AC_DEFINE([XP_HAVE_IN6_SCOPE_ID],[],[in6.scope_id])],
	[],
	[#include <sys/types.h> 
	 #include <sys/socket.h> 
	 #include <netinet/in.h>]
)

AC_CHECK_MEMBER(struct sockaddr_storage.ss_family,
	[AC_DEFINE([XP_HAVE_SS_FAMILY],[],[sockaddr_storage.ss_family])],
	[],
	[#include <sys/types.h> 
	 #include <sys/socket.h> 
	 #include <netdb.h>]
)

dnl check functions
AC_CHECK_FUNCS([lseek64 stat64 fstat64 ftruncate64])
AC_CHECK_FUNCS([sigaction syslog])
AC_CHECK_FUNCS([getifaddrs])

AC_MSG_CHECKING([for va_copy])
AC_TRY_LINK(
	[#include <stdarg.h>],
	[
		va_list x, y;
		va_copy(x,y);
	],
	[
		AC_MSG_RESULT(yes)
		AC_DEFINE([XP_HAVE_VA_COPY], [1], [va_copy is available])
	],
	[AC_MSG_RESULT(no)]
)

AC_MSG_CHECKING([for __va_copy])
AC_TRY_LINK(
	[#include <stdarg.h>],
	[
		va_list x, y;
		__va_copy(x,y); 
	],
	[
		AC_MSG_RESULT(yes)
		AC_DEFINE([XP_HAVE___VA_COPY], [1], [__va_copy is available])
	],
	[AC_MSG_RESULT(no)]
)

dnl check data types
AC_CHECK_TYPE(long long, [AC_DEFINE([XP_HAVE_LONG_LONG],[],[long long])])
AC_CHECK_TYPE(long double, [AC_DEFINE([XP_HAVE_LONG_DOUBLE],[],[long double])])

AC_CHECK_TYPES(
	[struct xt_mark_target_info,
	 struct xt_mark_target_info_v1,
	 struct xt_mark_tginfo2,
	 struct xt_mark_info,
	 struct xt_mark_mtinfo1],
	[], [], 
	[#include <linux/netfilter/xt_MARK.h>]
)


AC_CHECK_SIZEOF(char)
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
AC_CHECK_SIZEOF(__int8)
AC_CHECK_SIZEOF(__int16)
AC_CHECK_SIZEOF(__int32)
AC_CHECK_SIZEOF(__int64)
AC_CHECK_SIZEOF(__int96)
AC_CHECK_SIZEOF(__int128)
AC_CHECK_SIZEOF(void *)
AC_CHECK_SIZEOF(float)
AC_CHECK_SIZEOF(double)
AC_CHECK_SIZEOF(long double)
AC_CHECK_SIZEOF(pid_t)
AC_CHECK_SIZEOF(wchar_t)

AC_DEFINE_UNQUOTED(XP_SIZEOF_CHAR, ${ac_cv_sizeof_char}, [sizeof(char)])
AC_DEFINE_UNQUOTED(XP_SIZEOF_SHORT, ${ac_cv_sizeof_short}, [sizeof(short)])
AC_DEFINE_UNQUOTED(XP_SIZEOF_INT, ${ac_cv_sizeof_int}, [sizeof(int)])
AC_DEFINE_UNQUOTED(XP_SIZEOF_LONG, ${ac_cv_sizeof_long}, [sizeof(long)])
AC_DEFINE_UNQUOTED(XP_SIZEOF_LONG_LONG, ${ac_cv_sizeof_long_long}, [sizeof(long long)])
AC_DEFINE_UNQUOTED(XP_SIZEOF___INT8, ${ac_cv_sizeof___int8}, [sizeof(__int8)])
AC_DEFINE_UNQUOTED(XP_SIZEOF___INT16, ${ac_cv_sizeof___int16}, [sizeof(__int16)])
AC_DEFINE_UNQUOTED(XP_SIZEOF___INT32, ${ac_cv_sizeof___int32}, [sizeof(__int32)])
AC_DEFINE_UNQUOTED(XP_SIZEOF___INT64, ${ac_cv_sizeof___int64}, [sizeof(__int64)])
AC_DEFINE_UNQUOTED(XP_SIZEOF___INT128, ${ac_cv_sizeof___int128}, [sizeof(__int128)])
AC_DEFINE_UNQUOTED(XP_SIZEOF_VOID_P, ${ac_cv_sizeof_void_p}, [sizeof(void*)])
AC_DEFINE_UNQUOTED(XP_SIZEOF_FLOAT, ${ac_cv_sizeof_float}, [sizeof(float)])
AC_DEFINE_UNQUOTED(XP_SIZEOF_DOUBLE, ${ac_cv_sizeof_double}, [sizeof(double)])
AC_DEFINE_UNQUOTED(XP_SIZEOF_LONG_DOUBLE, ${ac_cv_sizeof_long_double}, [sizeof(long double)])
AC_DEFINE_UNQUOTED(XP_SIZEOF_WCHAR_T, ${ac_cv_sizeof_wchar_t}, [sizeof(wchar_t)])

AC_DEFINE_UNQUOTED(XP_PACKAGE_VERSION, "${VERSION}", [package version])
AC_DEFINE_UNQUOTED(XP_PACKAGE_VERSION_MAJOR, $(echo ${VERSION} | cut -d. -f1), [major version number])
AC_DEFINE_UNQUOTED(XP_PACKAGE_VERSION_MINOR, $(echo ${VERSION} | cut -d. -f2), [minor version number])
AC_DEFINE_UNQUOTED(XP_PACKAGE_VERSION_PATCH, $(echo ${VERSION} | cut -d. -f3), [patch level])
AC_DEFINE_UNQUOTED(XP_PACKAGE_NAME,"${PACKAGE_NAME}", [package name])
AC_DEFINE_UNQUOTED(XP_PACKAGE_AUTHOR,"${PACKAGE_BUGREPORT}", [author's email address])

AC_C_BIGENDIAN(
        [AC_DEFINE([XP_ENDIAN_BIG],[],[Big Endian])],
        [AC_DEFINE([XP_ENDIAN_LITTLE],[],[Little Endian])],
        [AC_DEFINE([XP_ENDIAN_UNKNOWN],[],[Unknown Endian])])

AC_ARG_ENABLE([wchar], [AS_HELP_STRING(--enable-wchar,use wchar_t a default charater type when enabled (default. yes))],
	enable_wchar_is=$enableval,enable_wchar_is=yes)
if test "$enable_wchar_is" = "yes"
then
	AC_DEFINE([XP_CHAR_IS_WCHAR],[],[char is wchar])
	if test "${platform_win32}" = "yes" 
	then
		CFLAGS="$CFLAGS -DUNICODE -D_UNICODE"
		CXXFLAGS="$CXXFLAGS -DUNICODE -D_UNICODE"
	fi
else
	AC_DEFINE([XP_CHAR_IS_MCHAR],[],[char is mchar])
fi

AC_ARG_ENABLE([syscall], [AS_HELP_STRING(--enable-syscall,use the syscall() function to call system calls (default. no))],
	enable_syscall_is=$enableval,enable_syscall_is=no)
if test "${enable_syscall_is}" = "yes"
then
	AC_DEFINE([XP_USE_SYSCALL],[],[use the syscall() function])
fi


AC_ARG_ENABLE([debug], [AS_HELP_STRING(--enable-debug,build the library in the debug mode (default. no))],
	enable_debug_is=$enableval,enable_debug_is=no)
if test "$enable_debug_is" = "yes"
then
	[CFLAGS="$CFLAGS -g -D_DEBUG -UNDEBUG"]
	[CXXFLAGS="$CXXFLAGS -g -D_DEBUG -UNDEBUG"]
	AC_SUBST(BUILD_MODE, "debug")
else
	[CFLAGS="$CFLAGS -DNDEBUG -U_DEBUG"]
	[CXXFLAGS="$CXXFLAGS -DNDEBUG -U_DEBUG"]
	AC_SUBST(BUILD_MODE, "release")
fi
AC_ARG_ENABLE([cxx], [AS_HELP_STRING(--enable-cxx,build the library for C++ if a C++ compiler is available (default. yes))],
	enable_cxx_is=$enableval,enable_cxx_is=yes)
[test "${HAVE_CXX}" = "yes" || enable_cxx_is="no"]
AM_CONDITIONAL(ENABLE_CXX, test "${enable_cxx_is}" = "yes" )

AC_ARG_ENABLE([reentrant], [AS_HELP_STRING(--enable-reentrant,define _REENTRANT (default. yes))],
	enable_reentrant_is=$enableval,enable_reentrant_is=yes)
if test "$enable_reentrant_is" = "yes"
then
	[CFLAGS="$CFLAGS -D_REENTRANT -D_THREAD_SAFE"]
	[CXXFLAGS="$CXXFLAGS -D_REENTRANT -D_THREAD_SAFE"]
fi

AC_ARG_ENABLE([ipv4tables], [AS_HELP_STRING(--enable-ipv4tables,enable iptc library for ipv4 (default. no))],
	enable_ipv4tables_is=$enableval,enable_ipv4tables_is=no)
AM_CONDITIONAL(ENABLE_IPV4TABLES, test "${enable_ipv4tables_is}" = "yes" )

AC_ARG_WITH([kernel-include-path],
	[AS_HELP_STRING(--with-kernel-include-path,specify kernel include path)],
	[kernel_include_path=$withval])
if test -n "$kernel_include_path" 
then
	AC_SUBST(KERNEL_INCLUDE_PATH, "-I$kernel_include_path")
else
	AC_SUBST(KERNEL_INCLUDE_PATH, "")
fi

AC_CONFIG_FILES([
	Makefile
	include/Makefile
	include/xp/Makefile
	include/xp/bas/Makefile
	include/xp/sys/Makefile
	include/xp/net/Makefile
	include/xp/utl/Makefile
	include/xp/xli/Makefile
	include/xp/lnx/Makefile
	xp/Makefile
	xp/bas/Makefile
	xp/sys/Makefile
	xp/net/Makefile
	xp/utl/Makefile
	xp/xli/Makefile
	xp/lnx/Makefile
	test/Makefile
	test/xp/Makefile
	test/xp/bas/Makefile
])
AC_OUTPUT

[
echo
echo "-[SUMMARY]---------------------------------------------------------------"
echo "Configured for ${host}"
echo "  Build mode : ${BUILD_MODE}"
echo "  Installation directory: ${prefix}"
echo "  C compiler: ${CC} ${CFLAGS}"
echo "  C++ compiler: ${CXX} ${CXXFLAGS}"
echo "  C++ support: ${enable_cxx_is}"
echo "  Wide character: ${enable_wchar_is}"
echo "  Math library: ${LIBM}"
echo "-------------------------------------------------------------------------"
]
